<template>
  <view class="recorder">
    <view>
      <u-button :custom-style="{color: '#fff', backgroundColor: '#4070FF'}" size="mini" @click="popShow = true">
        <u-icon name="mic"></u-icon> <text style="margin-left: 8rpx">录制语音</text>
      </u-button>
    </view>
    <view class="popup">
      <u-popup mode="bottom" v-model="popShow" :border-radius="40" safe-area-inset-bottom>
        <view class="pop-header">
          <u-icon class="icon-close" name="arrow-down" size="32" color="#303133" @click="popShow = false"></u-icon>
          <text class="title">{{ title }}</text>
        </view>
        <view class="pop-content">
          <view>
            <slot></slot>
          </view>
          <!-- 点击录音 -->
          <view class="recorder-start" v-if="recording === 0">
            <view class="center-container">
              <view class="tips">最短{{minTime}}秒，最长{{maxTime}}秒</view>
              <image
                @click="start()"
                src="/static/img/home.png">
              </image>
              <view class="tips2">点击录音</view>
            </view>
          </view>

          <!-- 正在录音中 -->
          <view class="recorder-end" v-if="recording === 1" style="position: relative">
            <view style="width:100%;display: flex;align-items: center;justify-content:center;position: absolute;top: 48rpx">
              <waveform></waveform>
              <text style="margin: 0 12rpx">{{ recordTimeStr }}</text>
              <waveform></waveform>
            </view>
            <view class="center-container">
              <view class="tips">最短{{minTime}}秒，最长{{maxTime}}秒</view>
              <image
                @click="end"
                mode="heightFix"
                width="100%"
                height="160rpx"
                src="/static/img/my.png">
              </image>
              <view class="tips2">正在录音中…点击即可结束录音</view>
            </view>
          </view>

          <!-- 点击即可播放 -->
          <view class="recorder-play" v-if="recording === 2 && playing === 0" style="position: relative">
            <view style="width:100%;display: flex;align-items: center;justify-content:center;position: absolute;top: 48rpx">
              {{ playTimeStr }}
            </view>
            <view class="center-container">
              <view class="tips">最短{{minTime}}秒，最长{{maxTime}}秒</view>
              <image
                @click="playVoice"
                mode="heightFix"
                width="100%"
                height="160rpx"
                src="/static/img/home.png">
              </image>
              <view class="tips2">点击即可播放</view>
            </view>
            <view class="bottom-container">
              <view class="btn-box">
                <u-button :custom-style="{width: '100%'}" class="btn" size="medium" plain @click="handleCancel">取消</u-button>
                <u-button :custom-style="{width: '100%'}" class="btn" size="medium" type="primary" @click="handleSubmit">确定</u-button>
              </view>
            </view>
          </view>

          <!-- 点击即可停止播放 -->
          <view class="recorder-pause" v-if="recording === 2 && playing === 1" style="position: relative">
            <view style="width:100%;display: flex;align-items: center;justify-content:center;position: absolute;top: 48rpx">
              <waveform></waveform>
              <text style="margin: 0 12rpx">{{ playTimeStr }}</text>
              <waveform></waveform>
            </view>
            <view class="center-container">
              <view class="tips">最短{{minTime}}秒，最长{{maxTime}}秒</view>
              <u-image
                @click="stopVoice"
                mode="heightFix"
                width="100%"
                height="160rpx"
                src="/static/img/home.png">
              </u-image>
              <view class="tips2">播放中…点击即可停止</view>
            </view>
            <view class="bottom-container">
              <view class="btn-box">
                <u-button :custom-style="{width: '100%'}" class="btn" size="medium" plain @click="handleCancel">取消</u-button>
                <u-button :custom-style="{width: '100%'}" class="btn" size="medium" type="primary" @click="handleSubmit">确定</u-button>
              </view>
            </view>
          </view>
        </view>
      </u-popup>
    </view>
  </view>
</template>

<script>
import waveform from './Waveform.vue'

let recorderManager = null
let innerAudioContext = null
export default {
  components:{
    waveform
  },
  props: {
    title: {
      type: String,
      default: '录制语音'
    },
    maxTime: { // 录音最大时长，单位秒
      type: Number,
      default: 15
    },
    minTime: { // 录音最小时长，单位毫秒
      type: Number,
      default: 1
    }
  },
  data() {
    return {
      popShow: false,
      voice: null,
      timer: null, // 定时器
      recordTime: 0, // 已录制的时间
      recording: 0, // 0:未在录制，1:正在录制，2:录制完成
      playing: 0, // 0:未在播放，1:正在播放
      playTime: 0, // 已播放的时间
    }
  },
  computed: {
    recordTimeStr(){
      const m = parseInt(this.recordTime / 60)
      const s = this.recordTime % 60
      return  (m < 10 ? ('0' + m) : m) + ':' + (s < 10 ? ('0' + s) : s)
    },
    playTimeStr(){
      const m = parseInt(this.playTime / 60)
      const s = this.playTime % 60
      return  (m < 10 ? ('0' + m) : m) + ':' + (s < 10 ? ('0' + s) : s)
    }
  },
  watch: {
    popShow(newVal){
      if(newVal === false){
        this.handleCancel()
      }
    }
  },
  mounted() {
    uni.authorize({
      scope: 'scope.record',
      success: () => {
        recorderManager = uni.getRecorderManager()
        innerAudioContext = uni.createInnerAudioContext()
      }
    })
  },
  methods: {
    start() {
      recorderManager.start({
        format: 'mp3',
        duration: this.maxTime * 1000
      })
      this.recording = 1
      this.timer = setInterval(() => {
        this.recordTime++
      }, 1000)

      recorderManager.onStop((res) => {
        console.log('recorder stop' + JSON.stringify(res))
        if(this.popShow === false){
          this.recording = 0
        }
        else if (this.recordTime < this.minTime) {
          this.recording = 0
          uni.showToast({
            title: '不能小于' + this.minTime + '秒,请重新录制',
            icon: 'none'
          })
        } else {
          this.recording = 2
          this.voice = res
        }

        clearInterval(this.timer) // 清除计时器
        this.timer = null // 清除计时器
        this.recordTime = 0 // 清除计时
      })
    },
    end() {
      recorderManager.stop()
    },
    playVoice() {
      if (this.voice) {
        innerAudioContext.src = this.voice.tempFilePath
        innerAudioContext.play()
        this.playing = 1

        this.timer = setInterval(() => {
          this.playTime++
        }, 1000)

        innerAudioContext.onEnded(() => {
          this.stopVoice()

          uni.showToast({
            title: '播放结束',
            icon: 'none'
          })
        })
      }
    },
    stopVoice() {
      innerAudioContext.stop()

      this.playing = 0
      this.playTime = 0
      clearInterval(this.timer)
      this.timer = null
    },
    handleSubmit(){
      this.$emit('submit', this.voice)
      this.popShow = false
    },
    handleCancel(){
      this.stopVoice()
      this.voice = null

      if(this.recording === 1) {
        this.end()
      } else {
        this.recording = 0
      }

    }
  }
}
</script>

<style lang="scss" scoped>
.popup {
  .pop-header {
    height: 104rpx;
    line-height: 104rpx;
    text-align: center;
    padding: 0 32rpx;

    .icon-close {
      height: 100%;
      float: left;
    }

    .title {
      margin-left: -32rpx;
      font-size: 32rpx;
      color: #303133;
    }
  }

  .pop-content {
    //height: 520rpx;
  }
}

.recorder-start,.recorder-end,.recorder-play,.recorder-pause {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background: #F7F8FA;
  height: 520rpx;

  .center-container {
    text-align: center;
    margin-bottom: 24rpx;

    .tips{
      font-size: 28rpx;
      text-align: center;
      color: #999;
      margin-bottom: 24rpx;
    }

    .tips2 {
      font-size: 28rpx;
      text-align: center;
      margin-top: 24rpx;
    }
  }
}

.bottom-container{
  display: flex;
  justify-content: space-between;
  align-items: center;
  height: 96rpx;
  width: 100%;
  position: absolute;
  bottom: 24rpx;
  padding: 0 24rpx;

  .btn-box{
    display: flex;
    width: 100%;

    .btn:first-child{
      flex: 1;
      margin-right: 12rpx;
    }
    .btn:last-child{
      flex: 1;
      margin-left: 12rpx;
    }
  }
}
</style>
